﻿/// <reference path="GMAPJSHelper_Release.js" />
/// <reference path="vswd-ext_2.2.js" />

/*************************************************
Author :Bill
Create : 2010-6-3
*/
var containClass;   
var BwinBmapIndex;
var BHwinBmapIndex;
var boxInfo = null;
var hboxInfo = null;
var startAddress, endAddress;
var allRouteShapes = new Array();
var EnumMapToolType = {
    Pan: 0,
    GeoFenceInAlarm: 1,
    GeoFenceOutAlarm: 2,
    AddPOI: 3,
    BeginEditMovePOI: 4,
    EndEditMovePOI: 5,
    CircleGeoFenceInAlarm: 6,
    CircleGeoFenceOutAlarm: 7,
    CircleGeoFenceInOutAlarm: 8
};

function myRouteHandler(route) {
    allRouteShapes.clear();
    var legs = route.RouteLegs;
    var turns = "";
    var leg = null;
    var turnNum = 0;
    var totalDistance = 0;
    for (var i = 0; i < legs.length; i++) {
        leg = legs[i];
        var turn = null;
        var legDistance = null;
        turns = "<table style='width:100%;'  frame='hsides'  rules='rows' style='border: 1px solid #CCCCCC;border-collapse:collapse'>";
        for (var j = 0; j < leg.Itinerary.Items.length; j++) {
            turnNum++;
            turn = leg.Itinerary.Items[j];
            var shape = turn.Shape;
            if (j > 0 && j < leg.Itinerary.Items.length - 1) {
                shape.Hide();
                turns += "<tr style='cursor:pointer' onclick='javascript:imap.map.HideInfoBox();imap.map.ShowInfoBox(allRouteShapes[" + (turnNum - 1) + "])' onmouseover='javascript:allRouteShapes[" + (turnNum - 1) + "].Show()' onmouseout='javascript:allRouteShapes[" + (turnNum - 1) + "].Hide()'><td style='width:.1' align='center'><a href='#' >" + turnNum + "<a></td><td style='width:80%;font-size: larger; font-weight: bold' align='left'>" + turn.Text;
            }
            else {
                turns += "<tr style='cursor:pointer' onclick='javascript:imap.map.HideInfoBox();imap.map.ShowInfoBox(allRouteShapes[" + (turnNum - 1) + "])'><td style='width:.1' align='center'><a href='#' >" + turnNum + "<a></td><td style='width:.8;font-size: larger; font-weight: bold' align='left'>" + turn.Text;
            }
            allRouteShapes.push(shape);
            legDistance = turn.Distance;
            totalDistance += legDistance;


            if (turn.Hints) {
                for (var k = 0; k < turn.Hints.length; k++) {
                    turns += "<p style='font-size:smaller; color:Gray'>" + turn.Hints[k].Text + "</p>";
                }

            }
            if (turn.Warnings) {
                for (var k = 0; k < turn.Warnings.length; k++) {
                    turns += "<p style='font-size:small; color:Gray'>" + turn.Warnings[k].Text + "</p>";
                }
            }
            var distanceString;
            if (legDistance.toFixed(1) < 1.0)
                distanceString = "(" + legDistance.toFixed(1)*1000 + _Turn_Meters+')'
            else
                distanceString = "(" + legDistance.toFixed(1) + _Turn_Miles+')'
            turns += "</td><td style='width:.1' align='right'>"+distanceString + "</td></tr>"

        }
        turns += "<tr><td colspan='2'></td><td  align='right'>&nbsp;&nbsp;" +_Turn_TotalMiles + ": " + totalDistance.toFixed(1) + _Turn_Miles+'</td></tr></table>';
    }
    dPanel.innerHTML = "<div style='padding-top:5px; padding-left:5px;padding-right:5px;'><div  style='background-color: #D9EDFF;border: 1px solid #000000;width:100%; padding-left:2px; vertical-align:middle'><image src='images/icon_greenA.png' style='vertical-align:middle'></image>" + _Turn_StartAddress+":" + startAddress + "</div></div><br>" + dPanel.innerHTML;
    dPanel.innerHTML += turns;
    dPanel.innerHTML += "<br><div style='padding-top:5px; padding-left:5px;padding-right:5px;'><div  style='background-color: #D9EDFF;border: 1px solid #000000;width:100%;  padding-right:2px; vertical-align:middle' align='right'>"+ _Turn_EndAddress+":" + endAddress + "<image src='images/icon_greenB.png' style='vertical-align:middle'></image></div></div></div>";
}
var dPanel = new Ext.Panel({});
VEMap.prototype.setContainerClass = function(obj) {
    this._containerclass = obj;
};

VEMap.prototype.getContainerClass = function() {
    return this._containerclass;
};

Array.prototype.clear = function() { this.length = 0; };

/***************************Auth:Winston create in 2010-5******************/
//google map Extent for LBS device Location drived by GOverlay

var svgNS = "http://www.w3.org/2000/svg"; 

if (document.createStyleSheet) {
    document.createStyleSheet().addRule("v\\:oval", "behavior:url(#default#VML);display:inline-block;");
    document.createStyleSheet().addRule("v\\:fill", "behavior:url(#default#VML);display:inline-block;");
    document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
}
else if (document.createElementNS) {
    //Browser Support SVG
}

function BExLBSDevice(point, d, imagesrc) {
    var shape = new VEShape(VEShapeType.Pushpin, point);
    this.radius = d / 2;
    var myIcon = new VECustomIconSpecification();
    myIcon.Image = imagesrc;
    shape.SetCustomIcon(myIcon);
    this.imagesrc = imagesrc;
    this.AddShape(shape);

}
BExLBSDevice.prototype = new VEShapeLayer();

BExLBSDevice.prototype.initialize = function(map) {
    var div = document.createElement("div");
    div.style.position = "absolute";
    this.AddShape(div);
    this.map = map;
    this.div = div;
};

// Remove the main DIV from the map pane
BExLBSDevice.prototype.remove = function() {
    this.div.parentNode.removeChild(this.div);
    //this.div2.parentNode.removeChild(this.div2);
};

// Copy our data to a new ExRectangle
BExLBSDevice.prototype.copy = function() {
    return new BExLBSDevice(this.point, this.radius, this.imagesrc);
};

BExLBSDevice.prototype.setLatLng = function(pt) {
    this.GetShapeByIndex(0).SetPoints(pt);
    this.redraw(true);
};

BExLBSDevice.prototype.getLatLng = function() {
    return this.GetShapeByIndex(0).GetPoints();
};
// Redraw the ExRectangle based on the current projection and zoom level

BExLBSDevice.prototype.redraw = function(force) {
    if (!force) return;
    //Clear all div items

    //this.div.innerHTML = "";
    var be = this.map.GetBirdseyeScene();
    var c3 = be.LatLongToPixel(map.GetCenter(), map.GetZoomLevel());
    var bounds = be.GetBoundingRectangle();
    var rect = be.GetBoundingRectangle();
    var southWest = rect.TopLeftLatLong;
    var northEast = rect.BottomRightLatLong;
    var r = Math.abs((this.radius / ((northEast.Longitute - southWest.Longitute) * 3.14 * 6370000 / 180)) * 710);
    this.div.style.width = 2 * r + "px";
    this.div.style.height = 2 * r + "px";
    this.div.style.left = (c3.x - r) + "px";
    this.div.style.top = (c3.y - r) + "px";
    if (document.createStyleSheet) {
        var bigoval = document.createElement("v:oval");
        bigoval.style.position = "absolute";
        bigoval.strokeColor = '#3399FF';
        bigoval.strokeWeight = 1;
        bigoval.style.left = 0;
        bigoval.style.top = 0;
        bigoval.style.width = 2 * r;
        bigoval.style.height = 2 * r;
        bigoval.style.opacity = 0.5;
        var MacdStroke = document.createElement('<v:fill opacity="0.1" color="#3399FF" />');
        bigoval.insertBefore(MacdStroke);
        this.div.appendChild(bigoval);

    }
    else if (document.createElementNS) {
        var content = document.createElementNS(svgNS, "svg");
        var bigoval = document.createElementNS(svgNS, "circle");
        bigoval.style.position = "absolute";
        bigoval.setAttribute("shape-rendering", false);
        bigoval.setAttribute("stroke-width", "1px");
        bigoval.setAttribute("stroke-color", '#3399FF');
        bigoval.setAttribute("r", (r - 1));
        bigoval.setAttribute("cx", (r + 1) + "px");
        bigoval.setAttribute("cy", (r + 1) + "px");
        bigoval.setAttribute("stroke", '#3399FF');
        bigoval.setAttribute("fill", "#3399FF");
        bigoval.setAttribute("fill-opacity", "0.1");
        bigoval.style.left = 4;
        bigoval.style.top = 4;
        content.appendChild(bigoval);
        this.div.appendChild(content);
    }
    var img = document.createElement("img");
    img.style.position = "absolute";
    img.src = this.imagesrc;
    var left = (r - img.width / 2);
    var top = (r - img.height / 2);
    img.style.left = left.toString() + "px";
    img.style.top = top.toString() + "px";
    this.div.appendChild(img);

};



function poiInfo(poiid, name, latitude, longitude, iconindex) {
    this.poiid = poiid;
    this.name = name;
    this.latitude = latitude;
    this.longitude = longitude;
    this.iconindex = iconindex;
};

/*******************************Class MSGMap ****************
this class packaged the google map and mlg function

**************************************************************/


var MSBMap = function(bmap, smallcontrol, fncallback, mapurl) {
    this.map = bmap; // the google map clasee
    originalMap = bmap;
    this.map.setContainerClass(this);
    if (smallcontrol) {
        this.map.SetDashboardSize(VEDashboardSize.Small);
    }
    else {
        this.map.SetDashboardSize(VEDashboardSize.Normal);
    }

    var itSelfClass = this;
    containClass = this.map.getContainerClass();
    //this.map.enableScrollWheelZoom();
    this._parkingTimeCap = "";
    this._trackerinfoLastArray = []; // array for tracker info 
    this._vehicleOverlayerArray = []; //array for last point vehicl
    this._labelOverlayerArray = []; //arry for last point vehicle lable
    this._bolfirsttimeload = true;
    this._bounds = null;
    this._isdragging = false;
    this._maptooltype = EnumMapToolType.Pan;
    this._dragrectbeginlatlng; //Drag rectangle being latlng
    this._dragrectendlatlng; //Drag rectangle end latlng
    this._dragRectangle;
    this.FnGeoFenceCallBack; // function call back for draw geo fence end
    this._preRadiusGeoFenceOverlay; //drag Geo fence  overlay
    this.FnCircleGeoFenceCallBack; // function circle geofence call back
    this._circleGeoFenceCenter; //the center of drag geofence
    this._circleEndLatLng; // the end latlng of drag geofence
    this._isFirstStartHistoryLine = true;
    this._realtimeTrackingLine; // realtime tracking google line overlay
    this._realtimeOverlayArray = []; //realtime point overlay array
    this.isFirstLoadRealLine = true;
    this._historyLine; //history tracking line overlay 
    this._historyOverlayArray = []; //history point overlay array

    this._poiOverlayArray = []; //all poi overlay
    this._addPOIOverlay; //add new poi overlay
    this._movePOIOverlay; //move poi overlay
    this._movePOIInfo;

    this._findOutLocationOverlay;
    var _msgmap = this;
    this._directions;
    this._startLocation;
    this._endLocation;
    this._previousmaptype = VEDashboardSize.Normal;
    this._submitcap = "Submit";
    this._cancelcap = "Cancel";
    this._parkingTimeCap = "";
    this._submitAddRouteCap = "";
    this._submitAddAllRouteCap = "";
    this._cancelAddRouteCap = "";
    this._editRouteID = null;
    this._closeCap = "";
    this._farCap = "";
    this._latitude = "Latitude";
    this._longitude = "Longitude";

    this._historyshowindex = 0;
    this._animateinterval = 1000;
    this._stopanimate = false;
    this._trackerhistoryinfoArray = [];
    this._historyshowtimer;
    this._gpsTimeCap = "";
    this._speedCap = "";
    this._directionPanel = null;
    this._historylineendfn = null;
    this._hidehistoryline = false;
    //static value
    var baseIcon = new VEShape(VEShapeType.Pushpin, new VELatLong(16, 16));
    baseIcon.SetIconAnchor(new VELatLong(16, 16));
    this.map.AttachEvent("onclick", function(overlay, latlng) {
        containClass.maponclick(overlay, latlng);
    })
    //    this.map.AttachEvent("onchangemapstyle", function() {
    //        containClass.reviseAllOverlay();
    //        //        if (_mapurl == "maps.google.com") {
    //        //            if (this.map.GetMapStyle() == VEMapStyle.Road) {
    //        //                this.getContainerClass().reviseAllOverlay();
    //        //            }
    //        //            else {
    //        //                if (this._previousmaptype == VEMapStyle.Road)
    //        //                    this.getContainerClass().unReviseAllOverlay();
    //        //            }
    //        //        }
    //        //        else if (_mapurl == "ditu.google.com") {

    //        //        }
    //        this._previousmaptype = containClass.map.GetMapStyle()
    //    });

    this.map.AttachEvent("onmousemove", function(e) {
        var msgmap = containClass;
        var point = msgmap.map.PixelToLatLong(new VEPixel(e.mapX, e.mapY));
        if (msgmap._maptooltype == EnumMapToolType.GeoFenceInAlarm || msgmap._maptooltype == EnumMapToolType.GeoFenceOutAlarm) {
            //Draw rectangle geoFence overlay
            if (msgmap._dragRectangle != null)
                msgmap.map.DeleteShape(msgmap._dragRectangle);
            if (msgmap._isdragging && (msgmap._dragrectbeginlatlng != null)) {
                var lineColor, fillColor;
                switch (msgmap._maptooltype) {
                    case EnumMapToolType.GeoFenceInAlarm:
                        lineColor = new VEColor(255, 0, 0, 0);
                        fillColor = new VEColor(255, 0, 0, 0.2);
                        break;
                    case EnumMapToolType.GeoFenceOutAlarm:
                        lineColor = new VEColor(0, 255, 0, 0);
                        fillColor = new VEColor(0, 255, 0, 0.2);
                        break;
                }
                msgmap._dragrectendlatlng = point;
                msgmap._dragRectangle = new VEShape(VEShapeType.Polygon, [
		            new VELatLong(msgmap._dragrectbeginlatlng.Latitude, msgmap._dragrectbeginlatlng.Longitude),
		            new VELatLong(msgmap._dragrectbeginlatlng.Latitude, point.Longitude),
		            new VELatLong(point.Latitude, point.Longitude),
		            new VELatLong(point.Latitude, msgmap._dragrectbeginlatlng.Longitude),
		            new VELatLong(msgmap._dragrectbeginlatlng.Latitude, msgmap._dragrectbeginlatlng.Longitude)
		        ]);

                msgmap._dragRectangle.SetLineWidth(1);
                msgmap._dragRectangle.SetLineColor(lineColor);
                msgmap._dragRectangle.SetFillColor(fillColor);
                msgmap._dragRectangle.SetCustomIcon("<div></div>");
                msgmap.map.AddShape(msgmap._dragRectangle);
            }
        }
        //Draw Moving POI overlay
        if (msgmap._maptooltype == EnumMapToolType.BeginEditMovePOI) {
            if (msgmap._movePOIInfo != null) {
                var poiid = msgmap._movePOIInfo.poiid;
                var name = msgmap._movePOIInfo.name;
                var lat = point.Latitude;
                var lng = point.Longitude;
                var iconindex = msgmap._movePOIInfo.iconindex;
                msgmap._movePOIInfo.Latitude = lat;
                msgmap._movePOIInfo.Longitude = lng;
                msgmap.drawMovePOI(poiid, name, lat, lng, iconindex, msgmap._submitcap, msgmap._cancelcap, null, null);
            }
        }
        //Draw Radius GeoFence overlay
        if (msgmap._maptooltype == EnumMapToolType.CircleGeoFenceInAlarm || msgmap._maptooltype == EnumMapToolType.CircleGeoFenceOutAlarm || msgmap._maptooltype == EnumMapToolType.CircleGeoFenceInOutAlarm) {
            if (msgmap._preRadiusGeoFenceOverlay != null)
                msgmap.map.DeleteShape(msgmap._preRadiusGeoFenceOverlay);
            if (msgmap._isdragging && (msgmap._circleGeoFenceCenter != null)) {
                var lineColor, fillColor;
                switch (msgmap._maptooltype) {
                    case EnumMapToolType.CircleGeoFenceInAlarm:
                        lineColor = new VEColor(255, 0, 0, 1);
                        fillColor = new VEColor(255, 0, 0, 0.2);
                        break;
                    case EnumMapToolType.CircleGeoFenceOutAlarm:
                        lineColor = new VEColor(0, 255, 0, 1);
                        fillColor = new VEColor(0, 255, 0, 0.2);
                        break;
                    case EnumMapToolType.CircleGeoFenceInOutAlarm:
                        lineColor = new VEColor(0, 64, 152, 1);
                        fillColor = new VEColor(0, 64, 152, 0.2);
                        break;
                }
                var ss = Math.sqrt(Math.pow(point.Latitude - msgmap._circleGeoFenceCenter.Latitude, 2) + Math.pow(point.Longitude - msgmap._circleGeoFenceCenter.Longitude, 2));
                msgmap._circleEndLatLng = point;
                msgmap.drawCircleGeoFence(msgmap._circleGeoFenceCenter.Latitude, msgmap._circleGeoFenceCenter.Longitude, ss, fillColor, lineColor, 0.2);
            }
        }
    });

    this.translateRecordToTrackerInfo = function(record) {
        var sssid = record.get("sssid");
        var devicename = record.get("devicename");
        var devicetype = record.get("devicetype");
        var gpsavailable = record.get("gpsavailable");
        var latitude = record.get("latitude");
        var longitude = record.get("longitude");
        var gpstime = record.get("gpstime");
        var receivedtime = record.get("receivedtime");
        var direction = record.get("direction");
        var speed = record.get("speed");
        var altitude = record.get("altitude");
        var devicestate = record.get("devicestate");
        var address = record.get("address");
        var alarminfo = record.get("alarminfo");
        var baseid = record.get("baseid");
        var hasgsmlocation = record.get("hasgsmlocation");
        var gsmlatitude = record.get("gsmlatitude");
        var gsmlongitude = record.get("gsmlongitude");
        var gsmaccuracy = record.get("gsmaccuracy");
        var iconname = record.get("iconname");
        var alarmcustomText = record.get("alarmcustomText");
        var gsm = null;
        if (hasgsmlocation) {
            gsm = new GSMInfo(gsmlatitude, gsmlongitude, 0, gsmaccuracy, "");
        }
        var tinfo = new TrackerInfo(sssid, devicename, devicetype, gpsavailable, longitude, latitude, gpstime, receivedtime, direction, speed, altitude, devicestate, address, alarminfo, gsm, null, null, null, iconname, alarmcustomText);
        return tinfo;
    };

    // google map china region revise
    this.reviseAllOverlay = function() {
        this.map.SetCenter(this.realLatLngToMapLatLng(this.map.GetCenter()));
        var i;
        for (i = 0; i < this._vehicleOverlayerArray.length; i++) {
            this._vehicleOverlayerArray[i].GetShapeByIndex(0).SetPoints(this.realLatLngToMapLatLng(this._vehicleOverlayerArray[i].GetShapeByIndex(0).GetPoints()))
        }
        for (i = 0; i < this._labelOverlayerArray.length; i++) {

            //var shape = new VEShape(VEShapeType.Pushpin,this.realLatLngToMapLatLng(this._labelOverlayerArray[i]));
            this._labelOverlayerArray[i].SetIconAnchor(this.realLatLngToMapLatLng(_labelOverlayerArray[i].GetIconAnchor()));
        }
        for (i = 0; i < this._realtimeOverlayArray.length; i++) {
            //            var mm = this._realtimeOverlayArray[i];
            //            mm.setLatLng(this.realLatLngToMapLatLng(mm.getLatLng()));
            this._realtimeOverlayArray[i].SetPoints(this._realtimeOverlayArray[i].GetPoints());
        }
        for (i = 0; i < this._historyOverlayArray.length; i++) {
            //            var mm = this._historyOverlayArray[i];
            //            mm.setLatLng(this.realLatLngToMapLatLng(mm.getLatLng()));
            this._historyOverlayArray[i].SetPoints(this._historyOverlayArray[i].GetPoints());
        }

        if (this._findOutLocationOverlay != null) {
            //            var mm = this._findOutLocationOverlay;
            //            mm.setLatLng(this.realLatLngToMapLatLng(mm.getLatLng()));
            this._findOutLocationOverlay[i].SetPoints(this._findOutLocationOverlay[i].GetPoints());
        }
        if (this._realtimeTrackingLine != null) {
            if (this._realtimeTrackingLine.GetPoints().length > 0) {
                var pts = [];
                var i;
                for (i = 0; i < this._realtimeTrackingLine.GetPoints().length; i++) {
                    var pt = this.realLatLngToMapLatLng(this._realtimeTrackingLine.GetPoints()[i]);
                    pts.push(pt);
                }
                var color = new VEColor(167, 116, 80, 1);
                var tmpline = new VEShape(VEShapeType.Polyline, pts)
                tmpline.SetLineColor(color);
                tmpline.SetLineWidth(2);
                //var tmpline = new GPolyline(pts, "#ff0000", 2);
                this.map.DeleteShape(this._realtimeTrackingLine);
                this._realtimeTrackingLine = tmpline;
                this.map.AddShape(this._realtimeTrackingLine);

            }
        }
        if (this._historyLine != null) {
            if (this._historyLine.GetPoints().length > 0) {
                var pts = [];
                var i;
                for (i = 0; i < this._historyLine.GetPoints().length; i++) {
                    var pt = this.realLatLngToMapLatLng(this._historyLine.GetPoints()[i]);
                    pts.push(pt);
                }
                var color = new VEColor(167, 116, 80, 1);
                var tmpline = new VEShape(VEShapeType.Polyline, pts)
                tmpline.SetLineColor(color);
                tmpline.SetLineWidth(2);
                //var tmpline = new GPolyline(pts, "#ff0000", 2);
                this.map.DeleteShape(this._historyLine);
                this._historyLine = tmpline;
                this.map.AddShape(this._historyLine);
            }
        }
    };

    //google map china region unrevise
    this.unReviseAllOverlay = function() {
        this.map.SetCenter(this.mapLatLngToRealLatLng(this.map.GetCenter()));
        var i;
        for (i = 0; i < this._vehicleOverlayerArray.length; i++) {
            this._vehicleOverlayerArray[i].GetShapeByIndex(0).setLatLng(this.mapLatLngToRealLatLng(this._vehicleOverlayerArray[i].GetShapeByIndex(0).GetPoints()))
        }
        for (i = 0; i < this._labelOverlayerArray.length; i++) {

            //var shape = new VEShape(VEShapeType.Pushpin,this.mapLatLngToRealLatLng(this._labelOverlayerArray[i]));
            this._labelOverlayerArray[i].SetIconAnchor(this.mapLatLngToRealLatLng(_labelOverlayerArray[i].GetIconAnchor()));
        }
        for (i = 0; i < this._realtimeOverlayArray.length; i++) {
            //            var mm = this._realtimeOverlayArray[i];
            //            mm.setLatLng(this.mapLatLngToRealLatLng(mm.getLatLng()));
            this._realtimeOverlayArray[i].setLatLng(this._realtimeOverlayArray[i].GetPoints());
        }
        for (i = 0; i < this._historyOverlayArray.length; i++) {
            //            var mm = this._historyOverlayArray[i];
            //            mm.setLatLng(this.mapLatLngToRealLatLng(mm.getLatLng()));
            this._historyOverlayArray[i].setLatLng(this._historyOverlayArray[i].GetPoints());
        }

        if (this._findOutLocationOverlay != null) {
            //            var mm = this._findOutLocationOverlay;
            //            mm.setLatLng(this.mapLatLngToRealLatLng(mm.getLatLng()));
            this._findOutLocationOverlay[i].setLatLng(this._findOutLocationOverlay[i].GetPoints());
        }
        if (this._realtimeTrackingLine != null) {
            if (this._realtimeTrackingLine.GetPoints().length > 0) {
                var pts = [];
                var i;
                for (i = 0; i < this._realtimeTrackingLine.GetPoints().length; i++) {
                    var pt = this.mapLatLngToRealLatLng(this._realtimeTrackingLine.GetPoints()[i]);
                    pts.push(pt);
                }
                var color = new VEColor(167, 116, 80, 1);
                var tmpline = new VEShape(VEShapeType.Polyline, pts)
                tmpline.SetLineColor(color);
                tmpline.SetLineWidth(2);
                //var tmpline = new GPolyline(pts, "#ff0000", 2);
                this.map.DeleteShape(this._realtimeTrackingLine);
                this._realtimeTrackingLine = tmpline;
                this.map.AddShape(this._realtimeTrackingLine);

            }
        }
        if (this._historyLine != null) {
            if (this._historyLine.GetPoints().length > 0) {
                var pts = [];
                var i;
                for (i = 0; i < this._historyLine.GetPoints().length; i++) {
                    var pt = this.mapLatLngToRealLatLng(this._historyLine.GetPoints()[i]);
                    pts.push(pt);
                }
                var color = new VEColor(167, 116, 80, 1);
                var tmpline = new VEShape(VEShapeType.Polyline, pts)
                tmpline.SetLineColor(color);
                tmpline.SetLineWidth(2);
                //var tmpline = new GPolyline(pts, "#ff0000", 2);
                this.map.DeleteShape(this._historyLine);
                this._historyLine = tmpline;
                this.map.AddShape(this._historyLine);
            }
        }
    };

    //gps real latlng to google map latlng,(china has revise)
    this.realLatLngToMapLatLng = function(latlng, noassertchina) {
        if (this.map.GetMapStyle() == VEMapStyle.Road) {
            if (noassertchina)
                return reviseLatLngForBMap(latlng);
            else
                return reviseRealLatLngToMapForBMap(latlng);
        }
        else
            return latlng;
    };

    //map latlng to real latlng
    this.mapLatLngToRealLatLng = function(latlng) {
        return unreviseMapLatLngForBMap(latlng);
    };

    //show new tracker in map
    this.showNewTrackerInfoOnMap = function(tinfo) {
        var pt = new VELatLong(tinfo.latitude, tinfo.longitude);
        if (tinfo.gsminfo != null) {
            pt = new VELatLong(parseFloat(tinfo.gsminfo.latitude), parseFloat(tinfo.gsminfo.longitude));
        }
        pt = this.realLatLngToMapLatLng(pt);
        //tinfo.setLabel(createTLabel(pt, tinfo.devicename, tinfo.speed + 'km/h', getAlarmStringFromAlarmType(tinfo.alarminfo), tinfo.gpstime));
        tinfo.setMarker(createMarker(pt, tinfo));
        this.drawNewTrackerInfo(tinfo);

    };

    this.removeTrackerInfo = function(trackerinfo) {
        var i;
        var alreadyhas = false;
        var index = -1;
        for (i = 0; i < this._trackerinfoLastArray.length; i++) {
            var tmptrackerinfo = this._trackerinfoLastArray[i];
            if (tmptrackerinfo.deviceid == trackerinfo.deviceid) {

                this.map.DeleteShapeLayer(tmptrackerinfo.marker);
                this._vehicleOverlayerArray.remove(tmptrackerinfo.marker); //
                index = i;
                alreadyhas = true;
                break;
            }
        }
        if (alreadyhas) {
            delete this._trackerinfoLastArray[index].marker;
            this._trackerinfoLastArray.remove(this._trackerinfoLastArray[index]);
        }
    };

    this.drawNewTrackerInfo = function(trackerinfo) {
        this.removeTrackerInfo(trackerinfo);
        this.map.AddShapeLayer(trackerinfo.marker);
        this._vehicleOverlayerArray.push(trackerinfo.marker);
        this._trackerinfoLastArray.push(trackerinfo);
    };

    this.changeTool = function(tool) {
        this._maptooltype = tool;
        switch (tool) {
            case EnumMapToolType.GeoFenceInAlarm:
            case EnumMapToolType.GeoFenceOutAlarm:
            case EnumMapToolType.CircleGeoFenceInAlarm:
            case EnumMapToolType.CircleGeoFenceOutAlarm:
            case EnumMapToolType.CircleGeoFenceInOutAlarm:
                imap.baseCls = 'dragzoom';
                break;
            case EnumMapToolType.Pan:
                imap.baseCls = 'pan';
                break;
            case EnumMapToolType.AddPOI:
                imap.baseCls = 'click';
                break;
            default:
                imap.baseCls = 'pan';
                break;
        }
    };

    this.maponclick = function(overlay) {
        var pixel = new VEPixel(overlay.mapX, overlay.mapY);
        var pt = this.map.PixelToLatLong(pixel);
        if (this._isdragging) {
            switch (this._maptooltype) {
                case EnumMapToolType.GeoFenceInAlarm:
                case EnumMapToolType.GeoFenceOutAlarm:
                    this._isdragging = false;
                    if (this._dragRectangle != null)
                        this.map.DeleteShape(this._dragRectangle);
                    if (this.FnGeoFenceCallBack != null) {
                        var ptbegin;
                        var ptend;
                        if (this.map.GetMapStyle() == VEMapStyle.Road) {
                            ptbegin = this.mapLatLngToRealLatLng(this._dragrectbeginlatlng);
                            ptend = this.mapLatLngToRealLatLng(this._dragrectendlatlng);
                        }
                        else {
                            ptbegin = this._dragrectbeginlatlng;
                            ptend = this._dragrectendlatlng;
                        }
                        this.FnGeoFenceCallBack(ptbegin.Latitude, ptbegin.Longitude, ptend.Latitude, ptend.Longitude);
                    }
                    this.changeTool(EnumMapToolType.Pan);
                    //this.map.enableDragging();
                    break;
                case EnumMapToolType.CircleGeoFenceInAlarm:
                case EnumMapToolType.CircleGeoFenceInOutAlarm:
                case EnumMapToolType.CircleGeoFenceOutAlarm:
                    this._isdragging = false;
                    if (this._preRadiusGeoFenceOverlay != null)
                        this.map.DeleteShape(this._preRadiusGeoFenceOverlay);
                    if (this.map.GetMapStyle() == VEMapStyle.Road) {
                        ptbegin = this.mapLatLngToRealLatLng(this._circleGeoFenceCenter);
                        ptend = this.mapLatLngToRealLatLng(this._circleEndLatLng);
                    }
                    else {
                        ptbegin = this._circleGeoFenceCenter;
                        ptend = this._circleEndLatLng;
                    }
                    var distance = getDistance(ptbegin, ptend);
                    if (this.FnCircleGeoFenceCallBack != null)
                        this.FnCircleGeoFenceCallBack(ptbegin.Latitude, ptbegin.Longitude, distance);
                    this.changeTool(EnumMapToolType.Pan);

                    //this.map.enableDragging();
                    break;
                default:
                    break;
            }
        }
        else {
            if (pt != null) {

                this._dragrectbeginlatlng = pt;
                switch (this._maptooltype) {
                    case EnumMapToolType.GeoFenceInAlarm:
                    case EnumMapToolType.GeoFenceOutAlarm:
                        this._isdragging = true;
                        break;
                    case EnumMapToolType.AddPOI:
                        this.drawAddPOI(pt.Latitude, pt.Longitude, 0, this._submitcap, this._cancelcap, "", "");
                        break;
                    case EnumMapToolType.CircleGeoFenceInAlarm:
                    case EnumMapToolType.CircleGeoFenceInOutAlarm:
                    case EnumMapToolType.CircleGeoFenceOutAlarm:
                        this._circleGeoFenceCenter = pt;
                        this._isdragging = true;
                        break;
                }
            }
            switch (this._maptooltype) {
                case EnumMapToolType.BeginEditMovePOI:
                    this.changeTool(EnumMapToolType.Pan);
                    var shape = this.map.GetShapeByID(overlay.elementID);
                    this.map.ShowInfoBox(shape);
                    break;
            }
        }
    };


    //create new TLabel.
    function createTLabel(point, username, speed, alarminfo, location) {
        //        var color = '#000';
        //        if (alarminfo.length > 0)
        //            color = '#FF0000';
        //        var content1 = '<div style="padding: 20px 0px 4px 20px; "><div style="background-color: #f2efe9; border: 1px solid #000; padding: 2px; font-family: arial; font-size: 11px; color: ' + color + '; text-decoration: none;"><nobr>' + username + ' ' + speed + ' ' + alarminfo + ' ' + location + '</nobr></div></div>';
        //        var label1 = new VEShape(VEShapeType.Pushpin, bmap.GetCenter())
        //        var rndInt = parseInt(Math.random() * 1000000);
        //        label1.SetCustomIcon(content1);
        //        return label1;


        //label1.percentOpacity = 80;
        //        return label1;
    }

    function createSimpleMarker(point) {
        //create a simple marker just by point , not finished ,just for immplement
    }
    //create new Marker
    function createMarker(point, trackerinfo) {
        var icon = new VEShape(VEShapeType.Pushpin, new VELatLong(0, 0));
        var marker;
        var direction = trackerinfo.direction;
        var speedkmh = parseInt(trackerinfo.speed);
        var myIcon = new VECustomIconSpecification();
        myIcon.TextContent = trackerinfo.devicename + ' ' + trackerinfo.speed + speedstr + '    ' + getAlarmStringFromAlarmType(trackerinfo.alarminfo) + ' ' + trackerinfo.gpstime;
        myIcon.TextSize = 8;
        myIcon.TextBold = false;
        myIcon.ForeColor = hasEmergencyAlarm(trackerinfo.alarminfo) ? new VEColor(255, 0, 0, 0.5) : new VEColor(41, 36, 33, 0.5);
        myIcon.TextOffset = new VEPixel(40, 20);
        var s = trackerinfo.devicetype;
        var imgsrc = trackerinfo.iconname != "" ? "images/trackericon/" + trackerinfo.iconname + "_" : "images/man.gif";
        if (trackerinfo.iconname != "") {
            if (direction == "East") {
                imgsrc += "n.png";
            }
            if (direction == "North") {
                imgsrc += "n.png";
            }
            if (direction == "South") {
                imgsrc += "n.png";
            }
            if (direction == "West") {
                imgsrc += "n.png";
            }
            else {
                imgsrc = "images/trackericon/" + trackerinfo.iconname;
                imgsrc += ".png";
            }
        }

        myIcon.Image = imgsrc;
        icon.SetCustomIcon(myIcon);
        icon.SetPoints(point);
        marker = new VEShapeLayer();
        marker.id = trackerinfo.deviceid;
        marker.AddShape(icon);


        if (trackerinfo.gsminfo != null) {
            var lineColor = new VEColor(0, 255, 0, 1);
            var fillColor = new VEColor(0, 255, 0, 0.2);
            var circle = itSelfClass.drawCircle(point, trackerinfo.gsminfo.accuracy / 200000, fillColor, lineColor, 2, 0.5);
            marker.AddShape(circle);

        }
        return marker;
    }

    this.createStoppedMarker = function(point, win_html) {
        var icon = new VEShape(VEShapeType.Pushpin, point);
        var myIcon = new VECustomIconSpecification();
        myIcon.Image = "images/red-stop.png";
        myIcon.ImageOffset = new VEPixel(-1, -18);
        myIcon.TextSize = 12;
        myIcon.TextBold = true;
        myIcon.ForeColor = new VEColor(255, 0, 0, 1);
        myIcon.TextOffset = new VEPixel(11, -5);
        icon.SetCustomIcon(myIcon);
        if (win_html) {
            try {
                this.map.FindLocations(point, getAddress);
            }
            catch (Error) {
            }
        }
        function getAddress(address) {
            if (address.length > 0)
                win_html += address[0].Name;
            else
                win_html += _msgmap._latitude + ":" + latlng.Latitude.toString() + " " + _msgmap._longitude + ":" + latlng.Longitude.toString();
            icon.SetDescription(win_html);
        }
        icon.SetDescription(win_html);
        return icon;
    };
    this.createTrackBeginEndMarker = function(point, begin, win_html) {
        var icon = new VEShape(VEShapeType.Pushpin, new VELatLong(16, 32));
        var image;
        if (begin)
            image = 'images/icon_greenA.png';
        else
            image = 'images/icon_greenB.png';
        var myIcon = new VECustomIconSpecification();
        myIcon.Image = image;
        myIcon.ImageOffset = new VEPixel(0, -18);
        myIcon.TextSize = 12;
        myIcon.TextBold = true;
        myIcon.ForeColor = new VEColor(255, 0, 0, 1);
        myIcon.TextOffset = new VEPixel(11, -5);
        icon.SetPoints(point);
        icon.SetCustomIcon(myIcon);
        if (win_html) {
            try {
                this.map.FindLocations(point, getAddress);
            }
            catch (Error) {
            
            }
        }
        function getAddress(address) {
            if (address.length > 0)
                win_html += address[0].Name;
            else
                win_html += _msgmap._latitude + ":" + latlng.Latitude.toString() + " " + _msgmap._longitude + ":" + latlng.Longitude.toString();
            icon.SetDescription(win_html);
        }
        icon.SetDescription(win_html);
        return icon;
    };

    this.createAlarmLabel = function(point, username, speed, alarminfo, location) {
        var color = '#000';
        if (alarminfo.length > 0)
            color = 'red';
        var content1 = '<div style="padding: 20px 0px 4px 20px; "><div style="background-color: #f2efe9; border: 1px solid #000; padding: 2px; font-family: arial; font-size: 11px; color:" ' + color + '"; text-decoration: none;"><nobr>' + username + ' ' + speed + ' ' + alarminfo + ' ' + location + '</nobr></div></div>';
        var label1 = new TLabel();
        var rndInt = parseInt(Math.random() * 1000000);
        label1.id = 'label' + username + rndInt;
        label1.anchorLatLng = point;
        label1.anchorPoint = 'midLeft';
        label1.content = content1;
        label1.percentOpacity = 80;
        return label1;
    };

    this.createAlarmMarker = function(point, trackerinfo) {
        var icon = new VEShape(VEShapeType.Pushpin, new VELatLong(6, 20));
        var myIcon = new VECustomIconSpecification();
        myIcon.Image = 'images/caution.png';
        myIcon.TextContent = trackerinfo.devicename + ' ' + trackerinfo.speed + speedstr + '    ' + getAlarmStringFromAlarmType(trackerinfo.alarminfo) + ' ' + trackerinfo.gpstime;
        myIcon.TextSize = 10;
        myIcon.TextBold = true;
        myIcon.ForeColor = new VEColor(41, 36, 33, 1);
        myIcon.TextOffset = new VEPixel(40, 20);
        icon.SetCustomIcon(myIcon);
        var marker;
        if (trackerinfo.gsminfo != null) {
            marker = new BExLBSDevice(point, trackerinfo.gsminfo.accuracy, "images/caution.gif");
        }
        else {
            icon.SetPoints(point);
            marker = new VEShapeLayer();
            marker.AddShape(icon);
        }
        return marker;
    };

    this.createTrackMarker = function(point, directionString, win_html) {
        var icon = new VEShape(VEShapeType.Pushpin, new VELatLong(0, 0));
        var direction = directionString;
        var baseImagePath;
        baseImagePath = "images/blue_";
        var tmarker = new VEShapeLayer();

        if (direction == "East") {
            icon.image = baseImagePath + "e.png";
        }
        if (direction == "North") {
            icon.image = baseImagePath + "n.png";
        }
        if (direction == "South") {
            icon.image = baseImagePath + "s.png";
        }
        if (direction == "West") {
            icon.image = baseImagePath + "w.png";
        }

        var myIcon = new VECustomIconSpecification();
        myIcon.Image = icon.image;
        myIcon.ImageOffset = new VEPixel(-1, -16.1);
        myIcon.TextSize = 12;
        myIcon.TextBold = true;
        myIcon.ForeColor = new VEColor(255, 0, 0, 1);
        myIcon.TextOffset = new VEPixel(11, -5);
        icon.SetCustomIcon(myIcon);
        icon.SetPoints(point);
        if (win_html) {
            try {
                this.map.FindLocations(point, getAddress);
            }
            catch (Error) {
            }
        }
        function getAddress(address) {
            if (address.length > 0)
                win_html += address[0].Name;
            else
                win_html += _msgmap._latitude + ":" + latlng.Latitude.toString() + " " + _msgmap._longitude + ":" + latlng.Longitude.toString();
            icon.SetDescription(win_html);
        }
        icon.SetDescription(win_html);
        return icon;
    };

    if (fncallback != null)
        fncallback();
};

MSBMap.prototype = {

    checkResize: function() {

    }

    , setCenter: function(glntlng, zoom, type) {

        var pt = this.realLatLngToMapLatLng(glntlng); //--trans latlng-
        this.map.SetCenterAndZoom(pt, zoom);
        this.map.SetMapStyle(type);
    }

    , setCenterbyLatLng: function(lat, lng, zoom, type) {

        var pt = this.realLatLngToMapLatLng(new VELatLong(lat, lng)); //--trans latlng-
        this.map.SetCenterAndZoom(pt, zoom);
        if (type)
            this.map.SetMapStyle(type);
    }

    , removeFromMap: function(ids) {
        var index = -1;
        for (i = 0; i < this._trackerinfoLastArray.length; i++) {
            var tmptrackerinfo = this._trackerinfoLastArray[i];
            if (tmptrackerinfo.deviceid == ids) {
                index = i;
                break;
            }
        }
        if (index >= 0)
            this.removeTrackerInfo(this._trackerinfoLastArray[index]);
    }

    , drawFromStore: function(pstore, bolcenter) {
        var count = pstore.getCount();
        var i;
        if (this._bolfirsttimeload) {
            //first login give bounds to browser map
            if (this._bounds != null)
                this._bounds = null;
            for (i = 0; i < count; i++) {
                var record = pstore.getAt(i);
                var tinfo = this.translateRecordToTrackerInfo(record);
                var pt = new VELatLong(parseFloat(tinfo.latitude), parseFloat(tinfo.longitude));
                pt = this.realLatLngToMapLatLng(pt);
            }
            if (pt != undefined)
                this.map.SetCenterAndZoom(pt, 14);
            this._bolfirsttimeload = false;
        }
        var lasttinfo;
        for (i = 0; i < count; i++) {
            var record = pstore.getAt(i);
            var tinfo = this.translateRecordToTrackerInfo(record);
            lasttinfo = tinfo;

            this.showNewTrackerInfoOnMap(tinfo);
        }
        if (bolcenter && (lasttinfo != null)) {
            var pt = new VELatLong(lasttinfo.latitude, lasttinfo.longitude);
            if (lasttinfo.gsminfo != null)
                pt = new VELatLong(parseFloat(lasttinfo.gsminfo.latitude), parseFloat(lasttinfo.gsminfo.longitude));
            pt = this.realLatLngToMapLatLng(pt); //--trans latlng-
            this.map.SetCenterAndZoom(pt, 14);
        }
    }

    // here fncallback must be a function with 1 string parameters
    , geoCoder: function(lati, longi, fncallback) {
        var latlng = new VELatLong(lati, longi);
        latlng = this.realLatLngToMapLatLng(latlng);
        try {
            this.map.FindLocations(latlng, GetResults);
        }
        catch (Error) {
        }
        function GetResults(locations) {
            if (locations) {
                address = locations[0].Name;
            }
            else {
                address = '';
            }
            fncallback(address, 1);
        }
    }
    , beginDrawGeoFence: function(inout) {
        if (inout == 0)
            this.changeTool(EnumMapToolType.GeoFenceOutAlarm);
        else if (inout == 1)
            this.changeTool(EnumMapToolType.GeoFenceInAlarm);
    }

    , beginDrawCircleGeoFence: function(inout) {
        if (inout == 0)
            this.changeTool(EnumMapToolType.CircleGeoFenceOutAlarm);
        else if (inout == 1)
            this.changeTool(EnumMapToolType.CircleGeoFenceInAlarm);
        else
            this.changeTool(EnumMapToolType.CircleGeoFenceInOutAlarm);
    }

    , realtimeTracking: function(record, gpsTimeCap, speedCap) {
        var tinfo = this.translateRecordToTrackerInfo(record);
        if (tinfo) {
            var pt = new VELatLong(parseFloat(tinfo.latitude), parseFloat(tinfo.longitude));
            pt = this.realLatLngToMapLatLng(pt); //--trans latlng-
            var isGPSFlowingPoint = false; //is the point is gps flowing point
            if (this._realtimeTrackingLine == null) {
                this._realtimeTrackingLine = new VEShape(VEShapeType.Polyline, [pt, pt])
                var color = new VEColor(167, 116, 80, 1);
                this._realtimeTrackingLine.SetLineColor(color);
                this._realtimeTrackingLine.SetLineWidth(2);
                this._realtimeTrackingLine.SetCustomIcon("<div></div>");
                this.map.AddShape(this._realtimeTrackingLine);

            }
            else {
                var pts = this._realtimeTrackingLine.GetPoints();
                pts.push(pt);
                if (this.isFirstLoadRealLine) {
                    pts.remove(pts[0]);
                    this.isFirstLoadRealLine = false;
                }

                var lastpt = this._realtimeTrackingLine.GetPoints()[this._realtimeTrackingLine.GetPoints.length - 1];
                if (this._realtimeTrackingLine.GetPoints().length > 15) {////

                    pts.remove(pts[0]);
                }
                if (pts.length > 1) {
                    this._realtimeTrackingLine.SetPoints(pts);
                }
            }
            if (!isGPSFlowingPoint) {
                tinfo.direction = (tinfo.direction != null ? tinfo.direction : "0");
                var marker = this.createTrackMarker(pt, tinfo.direction);
                //var shape = marker.GetShapeByIndex(0);
                var WIN_HTML;
                var timetext = gpsTimeCap + ':' + tinfo.gpstime + '<BR/>';
                var speedtext = speedCap + ':' + tinfo.speed + speedstr + '<BR/>';
                WIN_HTML = timetext + speedtext;
                marker.SetDescription(WIN_HTML);
                if (this._realtimeOverlayArray.length < 15) {
                    this.map.AddShape(marker);
                    this._realtimeOverlayArray.push(marker);
                }
                else {
                    this.map.DeleteShape(this._realtimeOverlayArray[0]);
                    this._realtimeOverlayArray.remove(this._realtimeOverlayArray[0]);
                    this.map.AddShape(marker);
                    this._realtimeOverlayArray.push(marker);
                }
                this.map.AttachEvent("onmousemove", this.showInfoBoxRealTime);
            }
            else {
                var marker = this._realtimeOverlayArray[this._realtimeOverlayArray.length - 1];
                marker.SetPoints(pt);
            }
            //if (!this.map.getBounds().containsLatLng(pt))
            //this.map.SetCenter(new VELatLong(37.83,144))
        }
    }
    , showInfoBoxRealTime: function(e) {

        if (e.elementID != null) {
            var shape = null;
            var map = null;
            for (var i = 0; i < rtrakingWindows.length; i++) {
                if (rtrakingWindows[i].bmap.GetShapeByID(e.elementID) != null) {
                    shape = rtrakingWindows[i].bmap.GetShapeByID(e.elementID);
                    map = rtrakingWindows[i].bmap;
                    BwinBmapIndex = i;
                    break;
                }
            }
            if (boxInfo == null && map != null) {
                var point = shape.GetPoints()[0];
                var px = map.LatLongToPixel(point, map.GetZoomLevel());
                px.y -= 100;
                px.x += 20;
                point = map.PixelToLatLong(px);
                boxInfo = new VEShape(VEShapeType.Pushpin, point);
                boxInfo.SetCustomIcon("<div style='padding: 10px;background-color:White; width:250px; height:100px;  border:1px solid #999999; '>" + shape.GetDescription() + "</div>");
                map.AddShape(boxInfo);
                map.HideInfoBox();
            }
        }
        else {
            if (boxInfo && rtrakingWindows[BwinBmapIndex].bmap) {
                rtrakingWindows[BwinBmapIndex].bmap.DeleteShape(boxInfo);
                rtrakingWindows[BwinBmapIndex].bmap.HideInfoBox();
                boxInfo = null;
            }
        }

    }
    , showInfoBoxHistory: function(e) {

        if (e.elementID != null) {
            var shape = null;
            var map = null;
            for (var i = 0; i < TrackingHistroyWindows.length; i++) {
                if (TrackingHistroyWindows[i].bmap.GetShapeByID(e.elementID) != null) {
                    shape = TrackingHistroyWindows[i].bmap.GetShapeByID(e.elementID);
                    map = TrackingHistroyWindows[i].bmap;
                    BHwinBmapIndex = i;
                    break;
                }
            }
            if (hboxInfo == null && map != null) {
                var point = shape.GetPoints()[0];
                var px = map.LatLongToPixel(point, map.GetZoomLevel());
                px.y -= 100;
                px.x += 20;
                point = map.PixelToLatLong(px);
                hboxInfo = new VEShape(VEShapeType.Pushpin, point);
                hboxInfo.SetCustomIcon("<div  style='padding: 10px;background-color:White; z-index:1000000000;width:250px; height:100%; border:1px solid #999999; '>" + shape.GetDescription() + "</div>");
                map.AddShape(hboxInfo);
                map.HideInfoBox();
            }
        }
        else {
            if (hboxInfo && TrackingHistroyWindows[BHwinBmapIndex].bmap) {
                TrackingHistroyWindows[BHwinBmapIndex].bmap.DeleteShape(hboxInfo);
                TrackingHistroyWindows[BHwinBmapIndex].bmap.HideInfoBox();
                hboxInfo = null;
            }
        }

    }
    , drawHistoryPoint: function(record) {
        var lati = record.get("latitude");
        var longi = record.get("longitude");
        var direction = record.get("direction");
        var hasgsmlocation = record.get("hasgsmlocation");
        var pt = new VELatLong(lati, longi);
        if (hasgsmlocation) {
            pt = new VELatLong(record.get("gsmlatitude"), record.get("gsmlongitude"));
        }
        pt = this.realLatLngToMapLatLng(pt); //--trans latlng-
        var mm;
        var zoom = 14;
        if (hasgsmlocation) {
            var accuracy = record.get("gsmaccuracy");
            mm = new BExLBSDevice(pt, accuracy, "images/blue.gif");
            zoom = this.getZoomFromRadius(accuracy);
        }
        else
            mm = this.createTrackMarker(pt, direction);
        this.map.AddShape(mm);
        this.map.SetCenterAndZoom(pt, zoom);

    }
    , drawSennorEventPoint: function(record) {
        var startlati = record.get("StartAddress").split(',')[1];
        var startlongi = record.get("StartAddress").split(',')[0];
        var overlati = record.get("OverAddress").split(',')[1];
        var overlongi = record.get("OverAddress").split(',')[0];
        var pt1 = new VELatLong(startlati, startlongi);
        var pt2 = new VELatLong(overlati, overlongi);
        pt1 = this.realLatLngToMapLatLng(pt1); //--trans latlng-
        pt2 = this.realLatLngToMapLatLng(pt2); //--trans latlng-
        var mm, mm1;
        var zoom = 14;
        mm = this.createTrackMarker(pt1, 0);
        mm1 = this.createTrackMarker(pt2, 0);
        this.map.AddShape(mm);
        this.map.AddShape(mm1);
        this.map.SetCenterAndZoom(pt1, zoom);

    }
    , getZoomFromRadius: function(accuracy) {
        if (accuracy < 2500)
            zoom = 15;
        else if (accuracy > 2500 && accuracy < 5000)
            zoom = 13;
        else
            zoom = 12;
        return zoom;
    }
    , drawAlarmPoint: function(trackerinfo) {
        var pt = new VELatLong(trackerinfo.latitude, trackerinfo.longitude);
        if (trackerinfo.gsminfo != null)
            pt = new VELatLong(trackerinfo.gsminfo.latitude, trackerinfo.gsminfo.longitude);
        pt = this.realLatLngToMapLatLng(pt); //--trans latlng-
        trackerinfo.setMarker(this.createAlarmMarker(pt, trackerinfo));
        this.map.AddShapeLayer(trackerinfo.marker);
        var zoom = 14;
        if (trackerinfo.gsminfo != null)
            zoom = this.getZoomFromRadius(trackerinfo.gsminfo.accuracy);
        this.map.SetCenterAndZoom(pt, zoom);
    }

    , stopAnimate: function() {
        this._stopanimate = true;
    }
    , startAnimate: function() {
        this._stopanimate = false;
        this.showAnimate(this);
    }
    , speedUpAnimate: function() {
        this._animateinterval = this._animateinterval / 2;
    }
    , slowDownAnimate: function() {
        this._animateinterval = this._animateinterval * 2;
    }
    , toStartPoint: function() {
        this.map.DeleteAllShapes();
        this._historyshowindex = 0;
        this._isFirstStartHistoryLine = true;
        var points = [new VELatLong(0.0, 0.0), new VELatLong(0.0, 0.0)];

        if (this._historyLine != null) {
            this._historyLine = null
            var points = [new VELatLong(0.0, 0.0), new VELatLong(0.0, 0.0)];
            this._historyLine = new VEShape(VEShapeType.Polyline, points);
            this._historyLine.SetLineWidth(2);
            this._historyLine.SetLineColor(new VEColor(167, 116, 80, 1));
            this._historyLine.SetCustomIcon("<div></div>");
            this.map.AddShape(this._historyLine);
        }
        window.clearInterval(this._historyshowtimer);
        this.startAnimate();
    }
    , toEndPoint: function() {
        this.stopAnimate();
        this._historyshowindex = this._trackerhistoryinfoArray.length - 1;
        window.clearInterval(this._historyshowtimer);
        this.startAnimate();
    }
    , _showAnimate: function(obj) {
        return function() {
            obj.showAnimate(obj);
        }
    }
    , showAnimate: function(obj) {
        if (obj._historyshowindex < obj._trackerhistoryinfoArray.length && obj._stopanimate == false) {
            var vinfo = obj._trackerhistoryinfoArray[obj._historyshowindex];
            obj._historyshowindex++;
            pt = obj.realLatLngToMapLatLng(new VELatLong(parseFloat(vinfo.latitude), parseFloat(vinfo.longitude)));
            var WIN_HTML;
            var timetext = obj._gpsTimeCap + ':' + vinfo.gpstime + '<BR/>';
            var speedtext = obj._speedCap + ':' + vinfo.speed + speedstr + '<BR/>';
            var otherinfo = "";
            if (vinfo.otherinfo)
                otherinfo = vinfo.otherinfo + '<BR/>';
            WIN_HTML = timetext + speedtext + otherinfo;
            if (vinfo.stopped)
                WIN_HTML += obj._parkingTimeCap + ":" + vinfo.stoppedtime + '<BR/>';
            var mm;
            //            if (obj._historyshowindex == 1)
            //                mm = obj.createTrackBeginEndMarker(pt, true, WIN_HTML);
            //            else if (obj._historyshowindex == obj._trackerhistoryinfoArray.length)
            //                mm = obj.createTrackBeginEndMarker(pt, false, WIN_HTML);
            //            else 
            if (vinfo.stopped) {
                mm = obj.createStoppedMarker(pt, WIN_HTML);
            }
            else
                mm = obj.createTrackMarker(pt, vinfo.direction.toString(), WIN_HTML);
            mm.SetDescription(WIN_HTML);
            obj.map.AddShape(mm);
            obj._historyOverlayArray.push(mm);
            obj.map.SetCenter(pt);
            if (!this._hidehistoryline) {
                var pts = obj._historyLine.GetPoints();
                if (this._isFirstStartHistoryLine) {
                    pts.clear();
                    pts.push(pt);
                    pts.push(pt);
                    this._isFirstStartHistoryLine = false;
                }
                else {
                    pts.push(pt);
                }
                if (pts.length > 1) {
                    obj._historyLine.SetPoints(pts);
                }
            }
            //obj._historyLine.insertVertex(0, pt);
            obj._historyshowtimer = window.setTimeout(obj._showAnimate(obj), obj._animateinterval);
            if (obj._historyshowindex == obj._trackerhistoryinfoArray.length) {
                if (obj._historylineendfn != null)
                    obj._historylineendfn(obj); //call back
            }
        }

    }
    , drawAnimateHistoryLine: function(extdatastore, gpsTimeCap, speedCap, fnShowEndCallback, hideLine) {
        this._historylineendfn = fnShowEndCallback;
        this._hidehistoryline = (typeof (hideLine) != 'undefined' ? hideLine : false);
        this._gpsTimeCap = gpsTimeCap;
        this._speedCap = speedCap;
        //        if (this._historyLine != null) {
        //            this.map.DeleteShapeLayer(this._historyLine);
        //            this._historyLine == null;
        //        }
        //        var j;
        //        for (j = 0; j < this._historyOverlayArray.length; j++) {
        //            this.map.DeleteShapeLayer(this._historyOverlayArray[j]);
        //        }

        var i;

        for (i = 0; i < extdatastore.getCount(); i++) {
            var record = extdatastore.getAt(i);
            var lati = record.get("latitude");
            var longi = record.get("longitude");
            var gpstime = record.get("gpstime");
            var direction = record.get("direction");
            var speed = record.get("speed");
            var otherinfo = record.get("otherinfo");
            var stopped = record.get("stopped");
            var stoppedtime = record.get("stoppedtime");
            var historyinfo = new TrackerInfo("", "", "", "", longi, lati, gpstime, "", direction, speed, "", "", "", "", "", otherinfo, stopped, stoppedtime);
            this._trackerhistoryinfoArray.push(historyinfo);

        }

        //        if (this._historyLine != null) {
        //            this.map.DeleteShapeLayer(this._historyLine);
        //        }
        if (!this._hidehistoryline) {
            var points = [new VELatLong(0.0, 0.0), new VELatLong(0.0, 0.0)];

            this._historyLine = new VEShape(VEShapeType.Polyline, points);
            this._historyLine.SetLineWidth(2);
            this._historyLine.SetLineColor(new VEColor(167, 116, 80, 1));
            this._historyLine.SetCustomIcon("<div></div>")

            //this._historyLine = new GPolyline(points, "#ff0000", 2);
            try {
                this.map.AddShape(this._historyLine);
            }
            catch (err) {
            }
        }
        //this.map.SetZoomLevel(14);
        this.map.AttachEvent("onmousemove", this.showInfoBoxHistory);
        this.showAnimate(this);
    }
    , drawHistoryLine: function(extdatastore, gpsTimeCap, speedCap) {
        this._gpsTimeCap = gpsTimeCap;
        this._speedCap = speedCap;
        if (this._historyLine != null) {
            this.map.DeleteShapeLayer(this._historyLine);
            this._historyLine == null;
        }

        var j;
        for (j = 0; j < this._historyOverlayArray.length; j++) {
            this.map.DeleteShapeLayer(this._historyOverlayArray[j]);
        }
        this._historyOverlayArray.clear();

        var bounds = new VELatLongRectangle();
        var points = new Array();
        var i;
        for (i = 0; i < extdatastore.getCount(); i++) {
            var record = extdatastore.getAt(i);
            var lati = record.get("latitude");
            var longi = record.get("longitude");
            var gpstime = record.get("gpstime");
            var direction = record.get("direction");
            var speed = record.get("speed");
            var pt = new VELatLong(lati, longi);
            pt = this.realLatLngToMapLatLng(pt); //--trans latlng-
            bounds.extend(pt);
            points.push(pt);
            if (i == 0) {
                var bmarker = this.createTrackBeginEndMarker(pt, true);
                //                GEvent.addListener(bmarker, "mouseover", function() {
                //                    var WIN_HTML;
                //                    var timetext = gpsTimeCap + ':' + gpstime + '<BR/>';
                //                    var speedtext = speedCap + ':' + speed + 'km/h<BR/>';
                //                    WIN_HTML = timetext + speedtext;
                //                    bmarker.openInfoWindowHtml(WIN_HTML);
                //                });
                this.map.AddShape(bmarker);
                this._historyOverlayArray.push(bmarker);
            }
            else if (i == extdatastore.getCount() - 1) {
                var emarker = this.createTrackBeginEndMarker(pt, false);
                this.map.AddShape(emarker);
                this._historyOverlayArray.push(emarker);
            }
            else {
                if (i % 10 == 0) {
                    var marker = this.createTrackMarker(pt, direction);
                    this.map.AddShape(marker);
                    this._historyOverlayArray.push(marker);
                }
            }
        }
        if (points.length > 0) {
            this._historyLine = new VEShape(VEShapeType.Polygon, points);
            var color = new VEColor(167, 116, 80, 0.7);
            _historyLine.SetFillColor(color);
            _historyLine.SetLineWidth(2);

            this.map.AddShpae(this._historyLine);
            this.map.SetZoomLevel(this.map.getBoundsZoomLevel(bounds)); //??????
            this.map.setCenter(bounds.getCenter()); //??????
        }
        else {
        }
    }
 , findLocation: function(lat, lng, latiCap, longiCap) {
     var point = new VELatLong(lat, lng);
     var icon = new VEShape(VEShapeType.Pushpin, new VELatLong(6, 20));
     var myIcon = new VECustomIconSpecification();
     myIcon.Image = 'images/red.png';
     icon.SetCustomIcon(myIcon);
     icon.SetDescription(latiCap + point.Latitude.toString() + "," + longiCap + point.Longitude.toString());
     if (this._findOutLocationOverlay != null)
         this.map.DeleteShapeLayer(this._findOutLocationOverlay);
     this._findOutLocationOverlay = null;
     point = this.realLatLngToMapLatLng(point); //--trans latlng-
     var fmarker = new VEShapeLayer();
     fmarker.AddShape(icon);
     icon.SetPoints(point);
     this._findOutLocationOverlay = fmarker;
     this.map.AddShapeLayer(this._findOutLocationOverlay);
     this.map.SetCenterAndZoom(point, 14);
 }

    , removeFound: function() {
        if (this._findOutLocationOverlay != null)
            this.map.DeleteShapeLayer(this._findOutLocationOverlay);
        this._findOutLocationOverlay = null;
    }

    , findDirection: function(from, to, directionsPanel, language, fnload, fnerror) {
        this.clearDirection();
        dPanel = directionsPanel;
        dPanel.innerHTML = "";
        this.map.Find("", from, null, null, 0, 10, true, true, true, true, this.getStartAddess);
        this.map.Find("", to, null, null, 0, 10, true, true, true, true, this.getEndAddess);


    }

    , getStartAddess: function(layer, resultsArray, places, hasMore, veErrorMessage) {
        var address = null;
        if (places) {
            address = places[0].Name;
            startAddress = address;
        }
        else {
            address = ""
        }
        //dPanel.innerHTML = "<div style='padding-top:5px; padding-left:5px;padding-right:5px;'><div  style='background-color: #D9EDFF;border: 1px solid #000000;width:100%; padding-left:2px; vertical-align:middle'><image src='images/icon_greenA.png' style='vertical-align:middle'></image>" +_Turn_StartAddress +":" + address + "</div></div><br>" + dPanel.innerHTML;
    }

    , getEndAddess: function(layer, resultsArray, places, hasMore, veErrorMessage) {
        var address = null;
        if (places) {
            address = places[0].Name
            endAddress = address;
        }
        else {
            address = ""
        }

        if (startAddress != "" && endAddress != "") {
            var myOptions = new VERouteOptions();
            myOptions.RouteCallback = myRouteHandler;
            containClass.map.GetDirections([startAddress, endAddress], myOptions);
            // dPanel.innerHTML += "<br><div style='padding-top:5px; padding-left:5px;padding-right:5px;'><div  style='background-color: #D9EDFF;border: 1px solid #000000;width:100%;  padding-right:2px; vertical-align:middle' align='right'>"+_Turn_EndAddress+":" + address + "<image src='images/icon_greenB.png' style='vertical-align:middle'></image></div></div></div>";
        }

    }


    , clearDirection: function() {
        if (this._directions != null) {
            this._directions.clear();
            this.map.DeleteRoute();
        }
    }

	, drawPOI: function(poiid, name, lat, lng, iconindex, centermap) {
	    var icon = new VEShape(VEShapeType.Pushpin, new VELatLong(6, 20));
	    var myIcon = new VECustomIconSpecification();
	    myIcon.Image = "images/poi32.gif";
	    icon.SetCustomIcon(myIcon);
	    myIcon.TextContent = name;
	    myIcon.TextSize = 10;
	    myIcon.TextBold = true;
	    myIcon.ForeColor = new VEColor(255, 0, 0, 1);
	    myIcon.TextOffset = new VEPixel(30, -8);
	    icon.SetCustomIcon(myIcon);
	    var pt = this.realLatLngToMapLatLng(new VELatLong(lat, lng));
	    ExMarker.prototype = new VEShape(VEShapeType.Pushpin, pt);
	    var marker = new ExMarker();
	    marker.ID = "POI-" + String(poiid);
	    marker.SetPoints(pt);
	    marker.SetCustomIcon(icon.GetCustomIcon());
	    this.map.AddShape(marker);
	    // pt, icon, false, '<div class="" style="position:absolute;left:30px;style: font-size: 10px;text-align:left"><font style="filter: glow(color=#0000FF,strength=3); height:20px; width:20px;color:blue; padding:1px"><span>' + name + '</span></font></div>');
	    this._poiOverlayArray.push(marker);
	    if (centermap) {
	        this.map.SetCenter(pt);
	    }
	}

	, beginAddPOI: function(submitcap, cancelcap) {
	    this._submitcap = submitcap;
	    this._cancelcap = cancelcap;
	    this.cancelAddEditPOI();
	    this.changeTool(EnumMapToolType.AddPOI);

	}

	, drawAddPOI: function(lat, lng, iconindex, submitcap, cancelcap, fnsubmitname, fncancelname) {
	    if (this._addPOIOverlay != null)
	        this.map.DeleteShape(this._addPOIOverlay);
	    var pt = new VELatLong(parseFloat(lat), parseFloat(lng));
	    var realpt = this.mapLatLngToRealLatLng(pt);
	    var WIN_HTML = '<div style="width: 12em; style: font-size: small"><INPUT id="textpoi" name="textpoi" value=""><INPUT id=butAddPOI type=button value=';
	    WIN_HTML += submitcap + ' name=submit onclick="return submitAddPOI(\'\',' + realpt.Latitude.toString() + ',' + realpt.Longitude.toString() + ',' + iconindex + ')">&nbsp;<INPUT id=butCancel type=button value=';
	    WIN_HTML += cancelcap + ' name=cancel onclick="cancelAddEditPOI()"></div>';
	    var icon = new VEShape(VEShapeType.Pushpin, new VELatLong(0, 0));
	    var myIcon = new VECustomIconSpecification();
	    myIcon.Image = 'images/poi32b.gif ';
	    icon.SetCustomIcon(myIcon);
	    ExMarker.prototype = new VEShape(VEShapeType.Pushpin, pt);
	    ExMarker.prototype.SetCustomIcon(icon.GetCustomIcon());
	    this._addPOIOverlay = new ExMarker(pt, icon, false, '', WIN_HTML);
	    this.map.AddShape(this._addPOIOverlay);
	    this._addPOIOverlay.SetDescription(WIN_HTML);
	}

    , beginEditMovePOI: function(poiid, lat, lng, iconindex, name, submitcap, cancelcap) {
        this._submitcap = submitcap;
        this._cancelcap = cancelcap;
        this._movePOIInfo = new poiInfo(poiid, name, lat, lng, iconindex);
        this.cancelAddEditPOI();
        this.changeTool(EnumMapToolType.BeginEditMovePOI);

    }

	, drawMovePOI: function(poiid, name, lat, lng, iconindex, submitcap, cancelcap, fnsubmitname, fncancelname) {
	    if (this._movePOIOverlay != null)
	        this.map.DeleteShape(this._movePOIOverlay);
	    var pt = new VELatLong(lat, lng);
	    var realpt = this.mapLatLngToRealLatLng(pt);
	    var WIN_HTML = '<div style="width: 12em; style: font-size: small"><INPUT id="textpoi" name="textpoi" value=""><INPUT id=butAddPOI type=button value=';
	    WIN_HTML += submitcap + ' name=submit onclick="return submitEditPOI(' + poiid + ',\'\',' + realpt.Latitude.toString() + ',' + realpt.Longitude.toString() + ',' + iconindex + ')">&nbsp;<INPUT id=butCancel type=button value=';
	    WIN_HTML += cancelcap + ' name=cancel onclick="cancelAddEditPOI()"></div>';
	    var icon = new VEShape(VEShapeType.Pushpin, new VELatLong(6, 20));
	    var myIcon = new VECustomIconSpecification();
	    myIcon.Image = 'images/poi32b.gif ';
	    icon.SetCustomIcon(myIcon);
	    ExMarker.prototype = new VEShape(VEShapeType.Pushpin, pt);
	    this._movePOIOverlay = new ExMarker(pt, icon, false, '<div class="" style="position:absolute;left:30px;style: font-size: 10px;text-align:left"><font style="filter: glow(color=#0000FF,strength=3); height:20px; width:20px;color:blue; padding:1px"><span>' + name + '</span></font></div>');
	    icon.SetPoints(pt);
	    this._movePOIOverlay.SetPoints(pt);
	    this._movePOIOverlay.SetCustomIcon(icon.GetCustomIcon());
	    this._movePOIOverlay.SetDescription(WIN_HTML);
	    this.map.AddShape(this._movePOIOverlay);
	}

    , cancelAddEditPOI: function() {
        if (this._addPOIOverlay != null)
            this.map.DeleteShape(this._addPOIOverlay);
        if (this._movePOIOverlay != null)
            this.map.DeleteShape(this._movePOIOverlay);
        this.map.HideInfoBox();
        this.changeTool(EnumMapToolType.Pan);
    }
    , deleteSelectedPOI: function(poiids) {
        var ids = String(poiids).split('|');
        for (var i = 0; i < ids.length; i++) {
            var id = ids[i];
            for (var j = 0; j < this._poiOverlayArray.length; j++) {
                if (this._poiOverlayArray[j].ID == 'POI-' + String(id)) {
                    this.map.DeleteShape(this._poiOverlayArray[j]);
                }
            }

        }
    }
    , drawPOIbyRecords: function(records) {
        this.hidePOI();
        var i = 0;
        for (i = 0; i < records.length; i++) {
            var record = records[i];
            var lat = record.get("latitude");
            var lng = record.get("longitude");
            var name = record.get("poiname");
            var poiid = record.get("poiid");
            var iconindex = record.get("iconindex");
            this.drawPOI(poiid, name, lat, lng, iconindex, false);
        }
    }


    , hidePOI: function() {
        while (this._poiOverlayArray.length > 0)
            this.map.DeleteShape(this._poiOverlayArray.pop());
    }

    // draw a Circle geofence on google map
    , drawCircleGeoFence: function(lat, lng, radius, fcolor, lcolor, thickness, opacity) {
        var center = new VELatLong(lat, lng);
        if (this._preRadiusGeoFenceOverlay != null)
            this.map.DeleteShape(this._preRadiusGeoFenceOverlay);
        this._preRadiusGeoFenceOverlay = this.drawCircle(center, radius, fcolor, lcolor, thickness, opacity);
        this.map.AddShape(this._preRadiusGeoFenceOverlay);
    }

    //javascript draw circle function
    , drawCircle: function(center, radius, bcolor, fcolor, thickness, opacity) {
        var circleQuality = 1;
        var M = Math.PI / 180;
        var circleSquish = 1.4;
        var points = [];
        for (var i = 0; i < 360; i += circleQuality) {
            var P = new VELatLong(center.Latitude + (radius * Math.sin(i * M)), center.Longitude + (radius * Math.cos(i * M)) * circleSquish);
            points.push(P);
        }
        points.push(points[0]);
        var p = new VEShape(VEShapeType.Polygon, points);
        p.SetFillColor(bcolor);
        p.SetLineColor(fcolor);
        p.SetCustomIcon("<div></div>");
        return p;
    }

    , setRouteCap: function(okCap, cancelCap, farCap, closeCap, allOkCap) {
        this._submitAddRouteCap = okCap;
        this._submitAddAllRouteCap = allOkCap;
        this._cancelAddRouteCap = cancelCap;
        this._farCap = farCap;
        this._closeCap = closeCap;
    }

     , findAddress: function(keywords, fn) {
         this.map.Find("", keywords, null, null, 0, 10, true, true, true, true, function getToAddresses(layer, resultsArray, places, hasMore, veErrorMessage) {
             if (places) {
                 var nameArray = [];
                 var latiArray = [];
                 var longiArray = [];
                 for (i = 0; i < places.length; i++) {
                     nameArray.push(places[i].Name);
                     latiArray.push(places[i].LatLong.Latitude);
                     longiArray.push(places[i].LatLong.Longitude);
                 }
                 fn(nameArray, latiArray, longiArray);
             }
         });
     }
};

